/*
 * @author Javier A. Ramírez M.
 * jaramirez85@yahoo.es
 */

package com.jav;


import com.sun.lwuit.Command;
import com.sun.lwuit.Dialog;
import com.sun.lwuit.List;
import com.sun.lwuit.animations.Transition3D;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import com.sun.lwuit.layouts.BorderLayout;
import com.sun.lwuit.list.DefaultListModel;
import com.sun.lwuit.util.Resources;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.io.file.FileSystemListener;
import javax.microedition.io.file.FileSystemRegistry;


public class Explorer extends Dialog implements FileSystemListener, Runnable, ActionListener {

    private List list;

     /**
	 * Separador de ficheros
	 */
	private final static String FILE_SEPARATOR = "/";
						         

	/**
	 * Directorio padre
	 */
	private final static String UPPER_DIR = "..";

	// Códigos de las posibles operaciones: Inicialización y apertura de ficheros
	private final static int LOAD_OP = 1;
	private final static int OPEN_OP = 2;

    private int    operationCode;
	private Thread task;

    private Vector roots;
	private FileConnection currentRoot;
    //private String FILE_FILTER = ".txt";
    private String FILE_FILTER = "__";

    private String urlFile="";

    public String getUrlFile() {
        return urlFile;
    }

    public void setUrlFile(String urlFile) {
        if(urlFile.trim().endsWith("..")){
            urlFile = urlFile.trim().substring(0, urlFile.trim().length()-2);
        }
        this.urlFile = urlFile;
    }

    public Explorer() {
        super("Explorer..");
        Resources res = Datos.getInstance().getRes();
        setTransitionInAnimator(Transition3D.createSwingIn(500));
        setTransitionOutAnimator(Transition3D.createSwingIn(500, false));
        setLayout(new BorderLayout());
        roots = new Vector();
        FileSystemRegistry.addFileSystemListener(Explorer.this);
        
        try{
            list = new List ();
            list.addActionListener(this);
            addComponent("Center", list);
            Command cmd_ok = new Command("Select",res.getImage("ok.png")){

                public void actionPerformed(ActionEvent evt) {
                    setUrlFile(currentRoot != null ? currentRoot.getURL():"file:///"  + (String) list.getSelectedItem() );
                    dispose();
                }
            };
            addCommand(cmd_ok);
            addCommand(new Command("Cancel",res.getImage("cancel.png")));
            operationCode = LOAD_OP;
            task = new Thread(this);
            task.start();
        }
        catch(Exception e){
            e.printStackTrace();
        }


    }

    public void rootChanged(int arg0, String arg1) {
        operationCode = LOAD_OP;
		task = new Thread(this);
		task.start();
    }

    private void loadRoots() {
		// Borramos los elementos que tuviese previamente
        
		roots.removeAllElements();

        // Solicitamos el dispositivo que nos proporcione la URL de las raices de todos los sistemas de ficheros LóGICOS

		Enumeration e_roots = FileSystemRegistry.listRoots();
		String      root  = null;
		while (e_roots.hasMoreElements()) {
			root  = (String) e_roots.nextElement();
			root  = FILE_SEPARATOR + root;           
            roots.addElement(root);
		}        
	}

    	/**
	 * Muestra en pantalla todos las raices encontradas
	 */
	private void displayAllRoots() {

		list.setModel(new DefaultListModel());

		Enumeration enum1 = roots.elements();
		String		root  = null;
		while (enum1.hasMoreElements()) {
			root = (String) enum1.nextElement();

			// El primer caracter es FileSelector.FILE_SEPARATOR. ==> lo descartamos.
			list.addItem(root.substring(1));
		}
		currentRoot = null;
        repaint();
	}

    /*
	 * Ejecuta la tarea en segundo plano.
	 * (En J2ME, todas las tareas de I/O deben ser en segundo plano.)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
        
		if (this.operationCode == LOAD_OP) {
			loadRoots();
			displayAllRoots();
		}
        else if (operationCode == OPEN_OP) {
            try {
                openSelected();

            } catch (IOException ex) {
                ex.printStackTrace();
            }
		}
	}

    private void openSelected() throws java.io.IOException {
		int		selectedIdx  = list.getSelectedIndex();
		String	url			 = null;
		String	selectedFile = null;

		if (selectedIdx < 0) {
			return;
		}
        
		selectedFile = (String) list.getSelectedItem();

		// abrir un directorio?

		if (selectedFile.endsWith(FILE_SEPARATOR) || selectedFile.endsWith("/")) {
			if (currentRoot == null) {
				currentRoot = (FileConnection) Connector.open("file:///" + selectedFile, Connector.READ);
			} else {
				currentRoot.setFileConnection(selectedFile);
			}
			displayCurrentRoot();
			return;
		}

		// Si Desea ir al directorio anterior?
        //imprimo los roots

		if (selectedFile.equals(UPPER_DIR)) {
            //falla porque para el sistema es \ y nunca lo encuentra en el vector roots
			if (roots.contains(currentRoot.getPath() + currentRoot.getName())) {                
				displayAllRoots();
			} else {
                try {
                    currentRoot.setFileConnection(UPPER_DIR);
                    displayCurrentRoot();
                } catch (Exception e) {
                    displayAllRoots();
                }
				
				
			}
			return;
		}

		// Es un fichero, lo mostramos.
        //setUrlFile(currentRoot.getURL() + selectedFile);
		//url = currentRoot.getURL() + selectedFile;
        //this.dispose();
		//.showTextFile(url);
	}

	/**
	 *  Muestra el contenido del directorio actual
	 */
	private void displayCurrentRoot() {
		Vector dirs    = new Vector();
		Vector files   = new Vector();
		String current = null;

		try {
			// Mostramos información sobre la ruta en el título.
			//this.setTitle(this.currentRoot.getURL());

			// Inicializamos la pantalla
			list.setModel(new DefaultListModel());

			// AÃ±adirmos la posibilidad de volver al directorio anterior
			dirs.addElement(UPPER_DIR);
            //this.append(FileSelector.UPPER_DIR, null);

			// Mostramos los directorios
			Enumeration enum1 = currentRoot.list("*", true);
			while (enum1.hasMoreElements()) {
				current = (String) enum1.nextElement();
				if (current.endsWith(FILE_SEPARATOR)) {
					dirs.addElement(current);   // Es un directorio
				} else {
                    if(current.toLowerCase().endsWith(FILE_FILTER)){ //solo los txt
                        files.addElement(current);  // Es un fichero
                    }
				}
			}

			showItems(dirs);   // AÃ±adimos los directorios a la pantalla
			showItems(files);  // AÃ±adimos los ficheros
		} catch (Exception e) {
			Dialog.show("ERROR\n"+e.getMessage(), this, new Command[]{new Command("OK")});
		}
	}

    /**
	 * Muestra los elementos de tipo string almacenados en un vector
	 */
	private void showItems(Vector items){
		Enumeration enum1   = items.elements();
		String      current = null;
		while (enum1.hasMoreElements()){
			current = (String) enum1.nextElement();
			list.addItem(current);
		}
	}

    public void actionPerformed(ActionEvent arg0) {
       operationCode = OPEN_OP;
       task = new Thread(this);
       task.start();      
    }



}
